package org.ndx.majick.ui.object;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Logger;

import javax.swing.JComponent;
import javax.swing.JLabel;

import org.ndx.majick.properties.Property;
import org.ndx.majick.ui.IClassUIProvider;
import org.ndx.majick.ui.IPropertyUIMetadata;
import org.ndx.majick.ui.IUIProvider;

/**
 * Object UI Provider is only a "fine" way for me to remind user something failed
 * @author Nicolas Delsaux
 *
 */
public class ObjectUIProvider implements IClassUIProvider {
	/**
	 * Class internal logger. MUST NOT be used anywhere else, for logs readability
	 */
	private static final Logger logger = Logger
			.getLogger(ObjectUIProvider.class.getName());

	public IPropertyUIMetadata createMetadata() {
		return new ObjectPropertyMetadata();
	}

	/**
	 * We can't edit an object.
	 * As a consequence, we will provide as editor a JLabel displaying some warnings, and additionnally we will add big messages in logs
	 */
	public JComponent getEditor(IPropertyUIMetadata metadata, Property<?> source) {
		JComponent returned = new JLabel("object "+source.getName()+" ("+source.getType().getName()+")");
		configureEditor(returned, metadata, source);
		return returned;
	}


	/**
	 * Configure returned component using infos from source and metadata.
	 * More specifically, the following operations are done :<ul>
	 * <li>Component name is set to be property one.</li>
	 * <li>A property change listener is registered on metadata to synchronize the UI state with the metadata one. (Notice that, for now, this introduces a vicious memory leak since I know no way to unregister it properly)</li>
	 * </ul>
	 * @param generated
	 * @param metadata
	 * @param source
	 */
	protected void configureEditor(final JComponent generated, final IPropertyUIMetadata metadata, final Property<?> source) {
		generated.setName(source.getName()+IUIProvider.EDITOR);
		if (metadata instanceof ObjectPropertyMetadata) {
			ObjectPropertyMetadata objectProperty = (ObjectPropertyMetadata) metadata;
			objectProperty.getReadOnly().addPropertyChangeListener(new PropertyChangeListener() {
				public void propertyChange(PropertyChangeEvent evt) {
					generated.setEnabled(!((Boolean) evt.getNewValue())); 
				}
			});
			generated.setEnabled(!objectProperty.getReadOnly().get());
		}
	}

	/**
	 * Configure returned viewer component
	 * @param generated
	 * @param metadata
	 * @param source
	 */
	protected void configureViewer(final JComponent generated, final IPropertyUIMetadata metadata, final Property<?> source) {
		generated.setName(source.getName()+IUIProvider.VIEWER);
	}

	public JComponent getViewer(IPropertyUIMetadata metadata, Property<?> source) {
		JComponent returned = new JLabel("object "+source.getName()+" ("+source.getType().getName()+")");
		configureViewer(returned, metadata, source);
		return returned;
	}
}
